﻿Public Class frmArtistSearch

    Private artistImages As ImageList

    Public Const ARTISTSEARCH_URL As String = "https://music.microsoft.com/Api/Catalog/media/en-US/singleMediaGroupSearch?firstPartyOnly=true&q={0}&maxItems=10&desiredMediaItemTypes=MusicArtist&desired=id.zuneid.name.genres"

    Private Sub frmArtistSearch_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        artistImages = New ImageList

        With artistImages
            .ImageSize = New Size(100, 100)
        End With

        lvResults.LargeImageList = artistImages

    End Sub

    Private Sub cmdSearch_Click(sender As Object, e As EventArgs) Handles cmdSearch.Click
        Try
            Me.Cursor = Cursors.WaitCursor
            cmdSearch.Enabled = False
            lvResults.Enabled = False
            Application.DoEvents()

            DoSearch()

        Finally
            cmdSearch.Enabled = True
            lvResults.Enabled = True
            Me.Cursor = Cursors.Default

        End Try

    End Sub

    Private Sub lvResults_DoubleClick(sender As Object, e As EventArgs) Handles lvResults.DoubleClick
        Me.DialogResult = DialogResult.OK
        Me.Close()
    End Sub

    Private Sub cmdClose_Click(sender As Object, e As EventArgs) Handles cmdClose.Click
        Me.Close()
    End Sub

    Private Sub DoSearch()
        Dim req As Net.HttpWebRequest
        Dim resp As Net.HttpWebResponse = Nothing
        Dim sr As IO.StreamReader = Nothing
        Dim wc As Net.WebClient = Nothing
        Dim response As String
        Dim result As SearchResult
        Dim li As ListViewItem
        Dim imageBytes() As Byte

        Try
            ' Clear grid
            lvResults.Items.Clear()
            artistImages.Images.Clear()

            req = DirectCast(Net.HttpWebRequest.Create(String.Format(ARTISTSEARCH_URL, Web.HttpUtility.UrlEncode(txtSearchText.Text))), Net.HttpWebRequest)
            With req
                .Method = "GET"
                .Accept = "application/json"
                .UserAgent = "HttpClient/4.1.1"
                .CookieContainer = New Net.CookieContainer
                .AuthenticationLevel = Net.Security.AuthenticationLevel.None
                With .Headers
                    .Add("X-Requested-With", "XMLHttpRequest")
                    .Add("x-xbl-client-type", "XboxCom")
                    .Add("x-xbl-contract-version", "3.2")
                    .Add("x-xbl-device-type", "Service")
                    .Add("x-xbl-client-version", "1.0")
                    .Add("x-xbl-build-version", "current")
                End With

            End With

            resp = DirectCast(req.GetResponse, Net.HttpWebResponse)

            Try
                sr = New IO.StreamReader(resp.GetResponseStream)
                response = sr.ReadToEnd

            Finally
                If sr IsNot Nothing Then sr.Dispose()
            End Try

            result = Newtonsoft.Json.JsonConvert.DeserializeObject(Of SearchResult)(response)

            If result.Items IsNot Nothing Then
                wc = New Net.WebClient

                ' collect all images
                For Each item As ResultItem In result.Items
                    Try
                        imageBytes = wc.DownloadData(New Uri(String.Format(frmArtist.ARTISTIMAGE_URL, item.ZuneId.ToString)))
                        artistImages.Images.Add(item.ZuneId.ToString, Bitmap.FromStream(New IO.MemoryStream(imageBytes)))

                    Catch ex As Exception
                        Debug.WriteLine(ex.Message)

                    End Try

                Next

                ' Add items to listview
                For Each item As ResultItem In result.Items
                    li = New ListViewItem(item.Name)
                    With li
                        .ImageKey = item.ZuneId.ToString
                        .SubItems.Add(New ListViewItem.ListViewSubItem With {.Name = "ZuneId", .Text = item.ZuneId.ToString})
                        .SubItems.Add(New ListViewItem.ListViewSubItem With {.Name = "ID", .Text = item.ID.ToString})
                    End With

                    lvResults.Items.Add(li)

                Next

            End If

        Finally
            If wc IsNot Nothing Then wc.Dispose()
            If resp IsNot Nothing Then resp.Dispose()
        End Try

    End Sub

End Class

'https://music.microsoft.com/Api/Catalog/media/en-US/singleMediaGroupSearch?firstPartyOnly=true&q=3%20doors%20down&maxItems=25&desiredMediaItemTypes=Album&desired=id.subtitle.name.trackcount.releasedate.primaryartist.zuneid.providers.genres.isexplicit
'https://music.microsoft.com/Api/Catalog/media/en-US/singleMediaGroupSearch?firstPartyOnly=true&q=3%20doors%20down&maxItems=25&desiredMediaItemTypes=Track&desired=id.subtitle.name.providers.parentalbum.primaryartist.releasedate.duration.zuneid.tracknumber.isexplicit
